﻿using DnD.Common;
using DnD.Model;
using Microsoft.Phone.Controls;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data.Linq.SqlClient;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace DnD.ViewModels
{
    class BrowseViewModel : INotifyPropertyChanged
    {
        private PhoneApplicationPage _view;
        private DnDRestService restService;

        private ObservableCollection<Card> _localCards;
        public ObservableCollection<Card> LocalCards
        {
            get { return _localCards; }
            set
            {
                _localCards = value;
                OnPropertyChanged();
            }
        }

        private Card _selectedLocalCard;

        public Card SelectedLocalCard
        {
            get { return _selectedLocalCard; }
            set
            {
                _selectedLocalCard = value;
                OnPropertyChanged();
                showCard(value);

            }
        }

        private ObservableCollection<Card> _onlineCards;
        public ObservableCollection<Card> OnlineCards
        {
            get { return _onlineCards; }
            set
            {
                _onlineCards = value;
                OnPropertyChanged();

            }
        }

        private Card _selectedOnlineCard;

        public Card SelectedOnlineCard
        {
            get { return _selectedOnlineCard; }
            set
            {
                _selectedOnlineCard = value;
                OnPropertyChanged();

                using (var context = new DnDDataContext(DnDDataContext.DbConnectionString))
                {
                    var cards = from c in context.GameItems.OfType<Card>() where c.OnlineID == value.OnlineID select c;
                    if (cards.Count() == 0)
                    {
                        value.Local = false;
                        context.GameItems.InsertOnSubmit(value);
                        context.SubmitChanges();
                    }
                    else
                    {
                        value = cards.First();
                    }
                }
                showCard(value);

            }
        }

        private ObservableCollection<Card> _myCards;
        public ObservableCollection<Card> MyCards
        {
            get { return _myCards; }
            set
            {
                _myCards = value;
                OnPropertyChanged();

            }
        }


        private Card _selectedMyCard;

        public Card SelectedMyCard
        {
            get { return _selectedOnlineCard; }
            set
            {
                _selectedMyCard = value;
                OnPropertyChanged();

                using (var context = new DnDDataContext(DnDDataContext.DbConnectionString))
                {
                    var cards = from c in context.GameItems.OfType<Card>() where c.OnlineID == value.OnlineID select c;
                    if (cards.Count() == 0)
                    {
                        value.Local = false;
                        context.GameItems.InsertOnSubmit(value);
                        context.SubmitChanges();
                    }
                    else
                    {
                        value = cards.First();
                    }
                }
                showCard(value);

            }
        }


        public ObservableCollection<Deck> LocalDecks { get; set; }
        public ObservableCollection<Deck> OnlineDecks { get; set; }
        
        public ObservableCollection<Deck> MyDecks { get; set; }

       
        public DelegateCommand SearchLocalCardsCommand { get; set; }
        public DelegateCommand SearchLocalDecksCommand { get; set; }
        public DelegateCommand SearchOnlineCardsCommand { get; set; }
        public DelegateCommand SearchOnlineDecksCommand { get; set; }
        public DelegateCommand SearchMyCardsCommand { get; set; }
        public DelegateCommand SearchMyDecksCommand { get; set; }

        private String _localCardSearchName;

        public String LocalCardSearchName
        {
            get { return _localCardSearchName; }
            set
            {
                _localCardSearchName = value;
                OnPropertyChanged();
                SearchLocalCardsCommand.CanExecute(value);
            }
        }

        private String _localCardSearchDesc;

        public String LocalCardSearchDesc
        {
            get { return _localCardSearchDesc; }
            set
            {
                _localCardSearchDesc = value;
                OnPropertyChanged();
                SearchLocalCardsCommand.CanExecute(value);

            }
        }

        private int _localCardSearchRate;

        public int LocalCardSearchRate
        {
            get { return _localCardSearchRate; }
            set
            {
                _localCardSearchRate = value;
                SearchLocalCardsCommand.CanExecute(value);
                OnPropertyChanged();

            }
        }


        private String _onlineCardSearchName;

        public String OnlineCardSearchName
        {
            get { return _onlineCardSearchName; }
            set
            {
                _onlineCardSearchName = value;
                OnPropertyChanged();
                SearchOnlineCardsCommand.CanExecute(value);
            }
        }

        private String _onlineCardSearchDesc;

        public String OnlineCardSearchDesc
        {
            get { return _onlineCardSearchDesc; }
            set
            {
                _onlineCardSearchDesc = value;
                OnPropertyChanged();
                SearchOnlineCardsCommand.CanExecute(value);

            }
        }

        private int _onlineCardSearchRate;

        public int OnlineCardSearchRate
        {
            get { return _onlineCardSearchRate; }
            set
            {
                _onlineCardSearchRate = value;
                OnPropertyChanged();
                SearchOnlineCardsCommand.CanExecute(value);
            }
        }

        private String _myCardSearchName;

        public String MyCardSearchName
        {
            get { return _myCardSearchName; }
            set
            {
                _myCardSearchName = value;
                OnPropertyChanged();
                SearchLocalCardsCommand.CanExecute(value);
            }
        }

        private String _myCardSearchDesc;

        public String MyCardSearchDesc
        {
            get { return _myCardSearchDesc; }
            set
            {
                _myCardSearchDesc = value;
                OnPropertyChanged();
                SearchMyCardsCommand.CanExecute(value);

            }
        }

        private int _myCardSearchRate;

        public int MyCardSearchRate
        {
            get { return _myCardSearchRate; }
            set
            {
                _myCardSearchRate = value;
                SearchMyCardsCommand.CanExecute(value);
                OnPropertyChanged();

            }
        }

        private bool _myCardSearchOnlineAlso;

        public bool MyCardSearchOnlineAlso
        {
            get { return _myCardSearchOnlineAlso; }
            set
            {
                _myCardSearchOnlineAlso = value;
                SearchMyCardsCommand.CanExecute(value);
                OnPropertyChanged();

            }
        }

       

        public BrowseViewModel(PhoneApplicationPage view)
        {
            

            SearchLocalCardsCommand = new DelegateCommand(searchLocalCards, name => LocalCardSearchName != "" || LocalCardSearchDesc != "" || LocalCardSearchRate !=0);
            SearchOnlineCardsCommand = new DelegateCommand(searchOnlineCards, name => OnlineCardSearchName != "" || OnlineCardSearchDesc != "" || OnlineCardSearchRate != 0);
            SearchMyCardsCommand = new DelegateCommand(searchMyCards, name => MyCardSearchName != "" || MyCardSearchDesc != "" || MyCardSearchRate != 0);



            OnlineCards = new ObservableCollection<Card>();

            restService = new DnDRestService();

            LocalCardSearchName = "";
            LocalCardSearchDesc = "";
            LocalCardSearchRate = 0;

            OnlineCardSearchName = "";
            OnlineCardSearchDesc = "";
            OnlineCardSearchRate = 0;

            MyCardSearchName = "";
            MyCardSearchDesc = "";
            MyCardSearchRate = 0;

            _view = view;

        }


        public void searchLocalCards(Object name)
        {
            using (var context = new DnDDataContext(DnDDataContext.DbConnectionString))
            {
                var query = context.GetTable<GameItem>().OfType<Card>();
                if (LocalCardSearchName != "")
                {
                    query = query.Where(card => SqlMethods.Like(card.Name, "%" + LocalCardSearchName + "%"));
                }
                if (LocalCardSearchDesc!= "")
                {
                    query = query.Where(card => SqlMethods.Like(card.Description, "%" + LocalCardSearchDesc + "%"));
                }
                if (LocalCardSearchRate != 0)
                {
                    query = query.Where(card => card.Rate >= LocalCardSearchRate);
                }
                LocalCards = new ObservableCollection<Card>(query);
                
            }

        }

        public void searchOnlineCards(Object name)
        {

            OnlineCards.Clear();

            restService.queryCards(OnlineCardSearchName,OnlineCardSearchDesc,"",OnlineCardSearchRate,0, OnlineCards);

        }

        public void searchMyCards(Object name)
        {
            if (UserViewModel.userName == null || UserViewModel.userName == "")
            {
                MessageBox.Show("Log in to see your cards!");
                return;
            }


            using (var context = new DnDDataContext(DnDDataContext.DbConnectionString))
            {
                var query = context.GetTable<GameItem>().OfType<Card>();
                if (MyCardSearchName != "")
                {
                    query = query.Where(card => SqlMethods.Like(card.Name, "%" + MyCardSearchName + "%"));
                }
                if (MyCardSearchDesc != "")
                {
                    query = query.Where(card => SqlMethods.Like(card.Description, "%" + MyCardSearchDesc + "%"));
                }
                if (MyCardSearchRate != 0)
                {
                    query = query.Where(card => card.Rate >= MyCardSearchRate);
                }
                query = query.Where(card => card.Author == UserViewModel.userName); 
                MyCards = new ObservableCollection<Card>(query);
            }

            if (MyCardSearchOnlineAlso)
            {
                restService.queryCards(MyCardSearchName, MyCardSearchDesc, UserViewModel.userName, OnlineCardSearchRate, 0, MyCards);

            }

        }


        public void showDeck(Object deck)
        {
            _view.NavigationService.Navigate(new Uri("/DeckPage.xaml?deckID=" + (deck as Deck).Id, UriKind.Relative));
        }

        public void showCard(Object card)
        {
            Card pressedCard = card as Card;


            _view.NavigationService.Navigate(new Uri("/CardPage.xaml?cardID=" + (pressedCard.Id).ToString(), UriKind.Relative));

        }

        public string BackGroundImageSource
        {
            get
            {
                if ((Visibility)App.Current.Resources["PhoneDarkThemeVisibility"]
                  == Visibility.Visible)
                {
                    return "/Assets/Pictures/fire5.jpg";

                }
                else
                {
                    return "/Assets/Pictures/fire5_negative.jpg";

                }
            }
            private set { }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
